/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import config.Debug;

/**
 * 
 * @author Yang Wang
 */
public class Unzipper {

	public static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
		byte[] buffer = new byte[1024];
		int len;

		while ((len = in.read(buffer)) >= 0) {
			out.write(buffer, 0, len);
		}

		in.close();
		out.close();
	}

	public static void unzip(File file, File dest) {
		if (file == null || dest == null) {
			return;
		}
		if (dest.isFile()) {
			return;
		}
		if (!dest.exists()) {
			dest.mkdir();
		}
		Enumeration entries;
		ZipFile zipFile;
		try {
			zipFile = new ZipFile(file);

			entries = zipFile.entries();
			Debug.msg("Unzipping " + file.getName());
			while (entries.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) entries.nextElement();

				if (entry.isDirectory()) {
					// Assume directories are stored parents first then
					// children.
					// Debug.msg("Extracting directory: " + dest.getPath() +
					// File.separator + entry.getName());
					// This is not robust, just for demonstration purposes.
					(new File(dest.getPath() + File.separator + entry.getName())).mkdir();
					continue;
				}
				File destFile = new File(dest, entry.getName());

				File destFileParent = destFile.getParentFile();
				destFileParent.mkdirs();
				// Debug.msg("Extracting file: " + destFile.toString());
				copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(destFile)));
			}

			zipFile.close();
		} catch (ZipException ex) {
			Debug.log("ZipException: " + ex.getMessage(), Debug.EXCEPTION_LEVEL);
		} catch (IOException ex) {
			Debug.log("IOException: " + ex.getMessage(), Debug.EXCEPTION_LEVEL);
		}
	}

	public void unzip(String zipFile) throws ZipException, IOException {

		int BUFFER = 2048;
		File file = new File(zipFile);

		ZipFile zip = new ZipFile(file);
		String newPath = zipFile.substring(0, zipFile.length() - 4);

		new File(newPath).mkdir();
		Enumeration zipFileEntries = zip.entries();

		// Process each entry
		while (zipFileEntries.hasMoreElements()) {
			// grab a zip file entry
			ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();

			String currentEntry = entry.getName();

			File destFile = new File(newPath, currentEntry);
			destFile = new File(newPath, destFile.getName());
			File destinationParent = destFile.getParentFile();

			// create the parent directory structure if needed
			destinationParent.mkdirs();
			if (!entry.isDirectory()) {
				BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
				int currentByte;
				// establish buffer for writing file
				byte data[] = new byte[BUFFER];

				// write the current file to disk
				FileOutputStream fos = new FileOutputStream(destFile);
				BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);

				// read and write until last byte is encountered
				while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
					dest.write(data, 0, currentByte);
				}
				dest.flush();
				dest.close();
				is.close();
			}
			if (currentEntry.endsWith(".zip")) {
				// found a zip file, try to open
				unzip(destFile.getAbsolutePath());
			}
		}
	}

	public static void main(String[] args) {
		File f = new File("test");
		System.out.println(Arrays.toString(f.list()));
		System.out.println(f.getAbsolutePath());
		unzip(new File("resources.zip"), new File("."));
	}
}
